#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""Generate HTML codes with python

It is so eazy.
"""


class Tag(object):
    """
    name: the name of the tag
    attrs: attributes of the tag
    """
    def __init__(self, name, **kwargs):
        self.name = name
        self.attrs = kwargs

    def __getitem__(self, k):
        return self.attrs[k]

    def __setitem__(self, k, v):
        self.attrs[k] = v

    def update(self, *args, **kwargs):
        self.attrs.update(*args, **kwargs)
    
    def __matmul__(self, attrs):
        self.update(attrs)
        return self

    def copy(self):
        import copy
        return copy.deepcopy(self)

    def __format__(self, spec=2):
        if spec.isdigit():
            spec = int(spec)
        else:
            raise Exception('unsupported format!')
        s = str(self)
        return '\n'.join(' '*spec + a for a in s.split('\n'))

    def dump(self, filename='test.html'):
        with open(filename, 'w') as fo:
            fo.write(str(self))


class DoubleTag(Tag):
    def __init__(self, name, children=None, **kwargs):
        self.name = name
        self.attrs = kwargs
        if children is None:
            self.children = []
        else:
            self.children = children

    def __gt__(self, other):
        if isinstance(other, Tag):
            self.children.append(other)
        else:
            self.children.extend(other)
        return self

    def __str__(self):
        a = []
        for k, v in self.attrs.items():
            if v is True:
                a.append('%v')
            elif v is False:
                continue
            else:
                a.append('%s="%s"' % (k,v))
        children = '\n'.join('  '+child if isinstance(child, str) else '{child:2}'.format(child=child) for child in self.children)
        if '\n' in children:
            return '<{name}{attrs}>\n{children}\n</{name}>'.format(name=self.name, attrs=' '+' '.join(a) if a else '', children=children)
        else:
            return '<{name}{attrs}>{children}</{name}>'.format(name=self.name, attrs=' '+' '.join(a) if a else '', children=children)


class SingleTag(Tag):
    def __str__(self):
        a = []
        for k, v in self.attrs.items():
            if v is True:
                a.append('%v')
            elif v is False:
                continue
            else:
                a.append('%s="%s"' % (k,v))
        return '<{name} {attrs}/>'.format(name=self.name, attrs=' '.join(a))

class Text(Tag):
    def __init__(self, content=''):
        self.content=content
    def __str__(self):
        return self.content

class LongText(Text):
    def __str__(self):
        return self.content.replace('\n', '<br/>')


class Comment(Text):
    def __str__(self):
        return '<!-- %s -->' % self.content

class Doc(Text):
    def __str__(self):
        return '<!DOCTYPE html>'


def double_tags(*args):
    for a in args:
        globals()[a] = DoubleTag(a)

def single_tags(*args):
    for a in args:
        globals()[a] = SingleTag(a)

double_tags('html', 'title', 'head', 'body', 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'span', 'font',
    'pre', 'ul', 'li', 'ol', 'table', 'th', 'td','tr', 'b', 'em', 'strong', 'xmp',
    'video', 'radio')
single_tags('img', 'br', 'meta', 'link')


if __name__ == '__main__':

    html > (
    head > (
        title,
        meta @ {"charset":"utf-8"},
        link @ {"rel":"stylesheet", "type":"text/css"}
    ), 
    body > (
        p > (LongText('I love zjc\nI love you'), 'Nihao', SingleTag('img', scr="hehe.jpg")), 
        Comment('It is a comment'),
        p > ('Welcome to zjc',  Text('Hello')),
        p > 'Is it easy?',
        DoubleTag('span', attrs={"class":"wow"}) > 'Wow'
    )
    )

